/*
* Company  : Datalogic Mobile Srl.
* Title    : Application in workdemo.BT2
* Filename : APL.C
* System   : Keil-Frankling C-Language Compiler
* MemoryMod: large
* Notes    : The Application is used to communicate with Host(PC)
             software(Systools) 
*/
//===============================================================================


/*********************************** INCLUDES *********************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "acqk.inc"    /* general acquisition constants */
#include "genk.inc"    /* general constants */
#include "iogenk.inc"  /* general i/o constants */
#include "acqdef.h"    /* definition of data structure related to acquisition */
#include "library.h"   /* definition of external procedures */
#include "hanswer.h"   /* handler answer external structures */

#pragma EJ
/********************************** CONSTANTS *********************************/
#define DIMINCODE                     1
#define DIMAXCODE                     8
#define DIMAXCODEBUF   DIMAXCODE   +  1
#define DIMINRES                      1
#define DIMAXRES                 	  8
#define DIMAXRESBUF     DIMAXRES  +   1
#define DIMINMEALS                    1
#define DIMAXMEALS                    4
#define DIMAXMEALSBUF  DIMAXMEALS +   1
#define DIMINAMT					  0
#define DIMAXAMT					  8
#define DIMAXAMTBUF  	DIMAXAMT +    1
#define DIMINPASS					  1
#define DIMAXPASS					  8
#define DIMAXPASSSBUF DIMAXPASS +	  1
#define DIMINMONTH					  0
#define DIMAXMONTH					  6
#define DIMAXMONTHBUF DIMAXMONTH +	  1
#define DIMINLOCATION				  1
#define DIMAXLOCATION 				  8
#define DIMAXLOCATIONBUF DIMAXLOCATION	+     1

#define PromptCodePosX                0 /* Prompt Position for Barcode */
#define PromptCodePosY                1
#define PromptRsPosX                  0 /* Prompt Position for ResidentId */
#define PromptRsPosY                  0
#define PromptMealsPosX			      0 /* Prompt Position for Meals */
#define PromptMealsPosY			      1
#define PromptPassPosX				  0	/* Prompt Position for Password */
#define PromptPassPosY				  2
			  

#define AnswerCodePosX                11 /* Answer Position for Barcode */
#define AnswerCodePosY                 1
#define AnswerRsPosX                   7/* Answer Position for ResidentId */
#define AnswerRsPosY                   1
#define AnswerMealsPosX			       7 /* Answer Position for Meals*/
#define AnswerMealsPosY			       2
#define AnswerPassPosX				   9 /* Answer Position for Password*/
#define AnswerPassPosY				   2
#define AnswerMonthPosX				   0 /*Answer Position For set Month */								
#define AnswerMonthPosY				   5
#define AnswerDatePosX				   3 /*Answer Position For set Date */
#define AnswerDatePosY				   5
#define AnswerYearPosX				   6 /*Answer Position For set Year */
#define AnswerYearPosY				   5



#define CODICE                     0
#define RESID                      1
#define MEALS					   2
#define DATA                       3
#define ORA                        4

#define DMP_DIRECTORY              1
#define DMP_ALL_RECORDS            2
#define DMP_ONE_RECORD             3
#define DMP_NNNN_RECORDS           4
#define DEL_ALL_RECORDS            5
#define DEL_ONE_RECORD             6
#define DEL_NNNN_RECORDS           7
#define ENQ_TERMINAL               8
#define DISPLAY_MSG_FIXED          9
#define DISPLAY_MSG_SCROLLING     10
#define DISPLAY_TERMINAL          11
#define DISPLAY_VERSION           12
#define DISPLAY_RAM               13
#define DISPLAY_AUTHOR            14
#define TX_STADDR                 15
#define SET_STADDR                16
#define TX_DATE_TIME              17
#define SET_DATE_TIME             18
#define NAK_COMMAND               19
#define NOTHING                   20


#define DMP_CMD               0x30   /* '0' */
#define DEL_CMD               0x31   /* '1' */
#define ENQ_CMD               0x35   /* '5' */
#define MSG_CMD               0x37   /* '7' */
#define LBL_CMD               0x38   /* '8' */

#define STX_CHR               0x02
#define ESC_CHR               0x1B
#define ETX_CHR               0x03
#define ACK_CHR               0x06
#define NAK_CHR               0x15
#define SOH_CHR				  0x01
#define EOB_CHR				  0x0d

#define DMP_LEN_MIN                4
#define DEL_LEN_MIN                4
#define MSG_LEN_MIN                3
#define MSG_LEN_MAX               35
#define LBL_LEN_MIN                3
#define LBL_LEN_MAX                4
#define REC_LEN_MAX                4
#define ENQ_LEN                    3

#define START_OF_BLOCK             0
#define STATION_ADDRESS            1
#define COMMAND                    2
#define CHK_HIGH_DIGIT             3
#define CHK_LOW_DIGIT              4
#define END_OF_BLOCK               5

#define Esc_Chr_Pos                0
#define Cmd_Chr_Pos                1
#define Cmd_Type_Chr_Pos           2

#define MAX_RX_BUFFER               0xFF

/*
* application task states
*/

#define FIRST_START            1   /* initialization at first activation */
#define CLEAR_START            2   /* clear display entry point */
#define MAIN_FRAME			   3   /* main frame wiht the clock */
#define ASK_CODE               4   /* decoder activation & buffer full check */
#define WAIT_CODE              5   /* waiting for answer */
#define ASK_RESID              6   /* decoder activation & buffer full check */				
#define WAIT_RESID 		       7   /* waiting for answer */
#define ASK_MEALS			   8   /* decoder activation & buffer full check */
#define WAIT_MEALS			   9   /* waiting for answer */
#define TRANSFER_DATA_VERIFY   10   /* verifiy if the user wants to trasfer data */	 
#define TRANSFER_DATA		   11   /* transfer data to the computer */ 	
#define WRITE_RECORD           12   /* search in dbase & display retrieved qty */
#define REVIEW_DATA			   13   /* review data from database */
#define DBASE_FULL             14   /* dbase full handling */
#define ASK_CONFIRM_DEL        15   /* ask record delete */
#define WAIT_CONFIRM_DEL       16   /* wait record delete confirmation */
#define TX_ACK                 17   /* Received correct frame, transmit ack char */
#define TX_NAK                 18   /* Received uncorrect frame, transmit nak char */
#define RX_ACK                 19   /* Transmit next frame */
#define RX_NAK                 20   /* Transmit last frame */
#define PREPARE_COMMUNICATION  21   /* Initialize serial communications */
#define ASK_PASS			   22
#define WAIT_PASS			   23
#define SETUP				   24
#define WAIT_SETMONTH 		   25
#define SETDATE			       26
#define WAIT_SETYEAR           27
#define WAIT_SETDATE		   28	
#define SETTIME				   29
#define WAIT_SETHOUR		   30
#define WAIT_SETMIN			   31
#define WAIT_SETSEC			   32
#define WAIT_DATEENTER 		   33
#define WAIT_TIMEENTER         34
#define SET_LOCATION		   35
#define WAIT_SETLOCATION       36
#define GUEST_MEALS            37
#define SPECIAL_CODE           38
#define SPECIAL_COUNT		   39
#define SPECIAL_AMOUNT         40
#define NEW_MEALCODES          41
#define WAIT_SPECIAL		   42
#define ASK_GUESTMEALS         43
#define WAIT_GUESTMEALS	       44
#define WAIT_SPECIALAMOUNT     45
#define WAIT_SPECIALCOUNT      46
#define WAIT_NEWMEALCODE       47
#define WAIT_GUESTMEALCODE     48
#define SPECIAL_CODES          49
#define ASK_NEWMEALCODE_MEALS  50
#define ASK_SPECIALENTER       51
#define DUPLICATE_RESID        52
#define RESET_DATA	           53
#define WAIT_RESET             54
#define RECEIVE_PROCESS_FRAME 55
#define REMOVE_USB_CABLE      56

#define FIRST_START        	1  		/* initialization at first activation */
#define ASK_DNAME	  		11		/* request for Device Name */
#define WAIT_DNAME			12		/* waiting for key board entry for device name */
#define ASK_DROLE			13		/* request for Device role */
#define WAIT_DROLE			14		/* waiting for key board entry for device role */
#define ASK_TPIN			15		/* request for 4 digit TPIN */
#define WAIT_TPIN			16		/* waiting for key board entry for TPIN */
#define ASK_SMODE			17		/* request for SCAN MODE entry */
#define WAIT_SMODE			18		/* waiting for key board entry for SCAN MODE value */
#define ASK_CMODE			19		/* request for CALL MODE entry */
#define WAIT_CMODE			20		/* waiting for key board entry for CALL MODE value */
#define ASK_RADDRESS		21		/* request for 16 digit ADDRESS entry */
#define WAIT_RADDRESS		22		/* waiting for key board entry for ADDRESS */
#define END					23		// 

#pragma EJ
/********************************** LOCALS ************************************/

static unsigned int nextstepBT;
static unsigned char reconfiguration_flag;
static unsigned char data bIsConnectionActive; //True if the connection is active



unsigned char tkaplON=0;
void prt_cfg_title(void );
void bt_Recfg_title(void);
void Connection_abort();
void  Connection_Monitor_start();



typedef struct dbase_record
{
  unsigned char location[DIMAXLOCATIONBUF];
  unsigned char barcode[ DIMAXCODEBUF ];
  unsigned char res[ DIMAXRESBUF ];
  unsigned char meals[ DIMAXMEALSBUF ];
  unsigned char amt[ DIMAXAMTBUF ];
  struct   time time_info;               // time & date are stored in numerical format
}dbase_rec;


struct dbase_record xdata *dbase;
struct dbase_record wr_record;
struct dbase_record rw_record;
struct dbase_record rd_record;

  
#define MAX_DBASE_BANKS   4
#define DBASE_BANK_ITEMS  (unsigned int) (RAMBANKUNITDIM / sizeof( dbase_rec ))
#define DBASE_ITEMS       MAX_DBASE_BANKS * DBASE_BANK_ITEMS  /* 2620 records */

typedef struct dbase_ph_index
{
	unsigned int  ix;
	unsigned int  bank;
	unsigned char *addr;
} dbase_ix;

struct dbase_ph_index cur_index;

static struct rtx_hreqst_message tx_hr_msg;
static struct rtx_hreqst_message rx_hr_msg;

static unsigned char tx_datab[ DimTxDataB ];

static unsigned char display_msg[ MSG_LEN_MAX + 1 ];
static unsigned char display_str[ 19 + 1 ];
static unsigned char nrec_str[ REC_LEN_MAX + 1 ];


static unsigned char prev_min = 0;
static unsigned char prev_sec = 0;

static unsigned int find_loop;
static unsigned int display_field;


static unsigned int nextstep;
static unsigned int laststep;

static unsigned int command_type;

static int irecx;
static int trecx;
static int frecx;

static unsigned char rx_status;  /* Reception routine status machine */

/* Control character of the communication frame */

static unsigned char start_of_block;
static unsigned char station_address;
static unsigned char end_of_text;
static unsigned char end_of_block;

static unsigned char checksum;      /* Used to calculate checksum of the receive frame */
static unsigned char rx_checksum;   /* Used to save the receive frame checksum */

static unsigned char inrx;          /* Pointer of reception buffer */
static unsigned char intx;          /* Pointer to the input tx buffer */
static unsigned char outtx;         /* Pointer to the output tx buffer */

static char communication_buffer[ MAX_RX_BUFFER ]; /* High level transmit buffer */
static char rx_buffer[ MAX_RX_BUFFER ]; /* Low level receive buffer */
static char tx_buffer[ MAX_RX_BUFFER ]; /* Low level transmit buffer */

static unsigned char wait_ack;      /* For ack/nak protocol */


static unsigned char defaultBarcode[9];  /* For saving barcode from barcode screen */
static unsigned char defaultLocation[9] ="";	 /*For saving location mode */
static unsigned char duplicateResidentId[9];
static unsigned int ifNotMealCode;
static unsigned int stringToInteger;
static unsigned int ifAcceptMealCode;
static unsigned int ifVerifyTransferData;
static unsigned int ifReviewData;
static unsigned int ifFirstPage;
static unsigned int ifAskCode;
static unsigned int ifMainFrame;
static unsigned int ifSetup;
static unsigned int ifSetYear;
static unsigned int monthInteger;
static unsigned int ifWaitSpecial;
static unsigned int ifGuestMeals;
static unsigned int ifNewMealCode;
static unsigned int ifSpecialCode;
static unsigned int ifResId;
static unsigned int ifMeals;
static unsigned int ifSpecialEnter;
static unsigned int ifAskResId;
static unsigned int ifAskConfirmDel;
static unsigned int ifWaitConfirmDel;
static unsigned int ifResetData;
static unsigned int ifDataPresent;

struct time changedTime;

unsigned char cfg_ret=0;
static unsigned char flag_config_set_bt3;
static unsigned char mode_3_flag;
#pragma EJ
/********************************* QUESTIONS **********************************/

code struct dec_hreqst_message DEC_QUESTION[ 3 ] =
{
{ MACQDEFAUL,DIMINCODE,DIMAXCODE,ACQNUMER,1,0,1,{"Meal Code:"},{""} },
{ MACQDEFAUL,DIMINRES,DIMAXRES,ACQALLPR,1,0,1,{"Res Id:"},{""} },
{ MACQDEFAUL,DIMINMEALS,DIMAXMEALS,ACQALLPR,1,PromptMealsPosX,PromptMealsPosY,{""},{""} },
};

code struct kb_hreqst_message KB_QUESTION[9 ] =
{												   
{ MACQAUTORP,DIMINCODE,DIMAXCODE,ACQNUMER,SECTCONSOL|SECTFUNCTN,0,1,{"Meal Code:"},{""} },
{ MACQAUTORP,DIMINRES,DIMAXRES,ACQALLPR,SECTCONSOL|SECTFUNCTN,0,1,{"Res Id:"},{""} },	
{ MACQAUTORP,DIMINMEALS,DIMAXMEALS,ACQALLPR,SECTCONSOL|SECTFUNCTN,0,2,{""},{""} },	
{ MACQAUTORP,        0,        0,ACQALLPR,SECTFUNCTN|SECTARROWS|SECTCONSOL, 0, 0, {""}, {""} },
{ MACQAUTORP,        0,        0,ACQALLPR,SECTARROWS           , 0, 0, {"\f    Database    \n      Full      "}, {""} },
{ MACQDEFAUL,DIMINPASS,DIMAXPASS,ACQNUMER,SECTCONSOL|SECTFUNCTN, PromptPassPosX, PromptPassPosY,{"Password:"},{""} },
{ MACQDEFAUL,DIMINMONTH,DIMAXMONTH,ACQNUMER,SECTCONSOL|SECTFUNCTN, 0, 0,{""},{""} },
{ MACQDEFAUL, DIMINLOCATION, DIMAXLOCATION, ACQALNUM, SECTCONSOL|SECTFUNCTN, 0, 1, {"Location:"}, {""} },
{ MACQDEFAUL, DIMINLOCATION, DIMAXLOCATION, ACQALLPR, SECTCONSOL|SECTFUNCTN, 0, 2, {""},{""}},
};


code struct kb_hreqst_message KB_QUESTION1[ 7 ] =
{
	{ MACQCAPSMA|MACQAUTORP,1,31,ACQALLPR,SECTCONSOL|SECTARROWS,0,1,{"\fDevice Name:         "},{""} },
	{ MACQAUTORP,1,1,ACQNUMER,SECTCONSOL,0,1,{"\fDeviceRole:(0-2)\n\n\n\n\n\n\n0 - Master\n\n1 - Slave\n\n2 - Master-Slave  "},{""} },
	{ MACQAUTORP,1,4,ACQNUMER,SECTCONSOL,0,1,{"\fTpin   :         "},{""} },
	{ MACQAUTORP,1,16,ACQNUMER,SECTCONSOL,0,1,{"\fHpin   :         "},{""} },
	{ MACQAUTORP,1,1,ACQNUMER,SECTCONSOL,0,1,{"\fScanMode:(0-3)\n\n\n\n0 - Discover OFF\n    Connect OFF\n\n1 - Discover ON\n    Connect OFF\n\n2 - Discover OFF\n    Connect ON\n\n3 - Discover ON\n    Connect ON    "},{""} },
	{ MACQAUTORP,1,1,ACQNUMER,SECTCONSOL,0,1,{"\fCallMode:(1-3)\n\n\n\n\n\n1 - START_CALL\n\n2 - WT_SPEC_CALL\n\n3 - WAIT_CALL    "},{""} },
	{ MACQCAPSMA|MACQAUTORP,1,12,ACQALNUM,SECTCONSOL|SECTARROWS,0,0,{"\fRemote Address:"},{""} },
};

#pragma EJ

/************************************ CODE ************************************/


/****************************** LOCAL  PROCEDURES *****************************/

/*
* Procedure that set the phisical index on current bank for the
* database.
*/

void ph_index( unsigned int logical_index )
{
  cur_index.ix    = ( logical_index % DBASE_BANK_ITEMS );
  cur_index.bank  = (unsigned int) ( logical_index / DBASE_BANK_ITEMS ) + SEL_RAMB1;
  cur_index.addr  = RAMBANKBASEADDR;
  cur_index.addr += ( cur_index.ix * sizeof( dbase_rec ) );
}

/*
 * Procedure that write a record on the phisical index of the current bank for database.
 */

void write_record( unsigned int logical_index, struct dbase_record xdata *wr_record )
{
  ph_index( logical_index );
 
  sv_currentbank();
  bankset( cur_index.bank );

  dbase  = (struct dbase_record *) cur_index.addr;
  *dbase = *wr_record;

  rp_previousbank();
}


/*
* Procedure that read a record on the phisical index of the current bank
* for database.
*/

void read_record( unsigned int logical_index )
{ 

	ph_index( logical_index );

	sv_currentbank();
	bankset( cur_index.bank );

	memcpy( &rd_record, cur_index.addr, sizeof( rd_record ) );

	rp_previousbank();
}

void turnOffOptions(){
	ifVerifyTransferData = FALSE;
	ifReviewData = FALSE;
	ifFirstPage = FALSE;
	ifAskCode = FALSE;
	ifMainFrame = FALSE;
	ifSetup = FALSE;
	ifSetYear = FALSE;
	monthInteger = FALSE;
	ifWaitSpecial = FALSE;
	ifGuestMeals = FALSE;
	ifNewMealCode = FALSE;
	ifNotMealCode = FALSE;
	ifSpecialCode = FALSE;
	ifResId = FALSE;
	ifMeals = FALSE;
	ifSpecialEnter = FALSE;
	ifAskResId = FALSE;
	ifAskConfirmDel = FALSE;
	ifWaitConfirmDel = FALSE;
	ifResetData = FALSE;
	ifDataPresent = FALSE;
}

void displayCurrentRecord(){

    printf( "\f" );
	gotoxy( 0, 1);
	printf("  REVIEW DATA");
	gotoxy( 0,3 );
	printf("REC#%uOF%u",frecx+1,irecx);
  	gotoxy( 0, 5 );
  	printf( "Meal Code:%s", rd_record.barcode );
  	gotoxy( 0, 6 );
  	printf( "Res Id:%s", rd_record.res);
  	gotoxy( 0, 7 );
  	printf( "Meals:%s", rd_record.meals);
	gotoxy( 0,8 );
	printf( "Amount:%s", rd_record.amt); 
  	gotoxy( 0, 9 );
  	printf( "Date:%02bu/%02bu/%02bu",
	           rd_record.time_info.month,
	           rd_record.time_info.day,
	           rd_record.time_info.year );
  	gotoxy( 0, 10 );
  	printf( "Time:%02bu:%02bu",
	           rd_record.time_info.hour,
	           rd_record.time_info.min);
	gotoxy(0, 12 );
    printf( "UP=Pre DWN=Next");
	gotoxy(0, 13 );
	printf("ESC=Del F4=Exit");

    slptsk( PROC_TKAPL );
}

unsigned char get_up_record()
{
  if( irecx == 0 )
      	return( NOK );
  
  	if( !find_loop )
  	{
    	/* last record */
    	frecx = irecx - 1;
    	if( frecx < 0 )
      	return( NOK );

    	read_record( frecx );
		displayCurrentRecord();	 
    	find_loop = TRUE;
   		return( OK );
  	}
  else
  {
    /* previous record */
    if( frecx-1 < 0 )
    {
	  	frecx = irecx - 1;
	  	read_record( frecx );
	  	displayCurrentRecord();	 
      	find_loop = TRUE;
	  	return(OK);
    }else{
    	frecx--;
    	read_record( frecx );
		displayCurrentRecord();	
    	return( OK );
	}
  }
}


unsigned char get_dwn_record()
{
  if( irecx == 0 )
      return( NOK );
  if( !find_loop )
  {
    frecx = 0;
    read_record( frecx );
	gotoxy(0,2);
	displayCurrentRecord();
    find_loop = TRUE;
    return( OK );
  }else{
    if( frecx+1 >= irecx )
    {
		frecx = 0;
    	read_record( frecx );
		gotoxy(0,2);
		displayCurrentRecord();
		return (OK);
	}else{
		frecx++;
    	read_record( frecx );
		gotoxy(0,2);
		displayCurrentRecord();
    	return( OK );
	}
  }
  return (OK);
}


/*
 * Display decoder barcode answer.
 */
void dec_answervis_code( void )
{
  int i;

  if( dec_answer.stat == ACQDIS ) return;

  gotoxy( AnswerCodePosX, AnswerCodePosY );
  printf( "                " ); /* clear field for backspace operation */
  gotoxy( 0, AnswerCodePosY+1 );
  printf( "                " ); /* clear field for backspace operation */
  gotoxy( 0, AnswerCodePosY+2 );
  printf( "                " ); /* clear field for backspace operation */

  gotoxy( AnswerCodePosX, AnswerCodePosY );
  if( strlen( dec_answer.datab ) <= 16 )
    printf( "%s", dec_answer.datab );
  else
  {
    for( i = 0; i <= 15; i++ )
       putchar( dec_answer.datab[ i ] );
    gotoxy( 0, AnswerCodePosY+1 );
    if( strlen( dec_answer.datab ) <= 32 )
      for( i = 16; i < strlen( dec_answer.datab ); i++ )
        putchar( dec_answer.datab[ i ] );
    else
    {
      for( i = 16; i <= 31; i++)
        putchar( dec_answer.datab[ i ] );
      gotoxy( 0, AnswerCodePosY+2 );
      for( i = 32; i < strlen( dec_answer.datab ); i++)
        putchar( dec_answer.datab[ i ] );
    }
  }
}

/*
 * Display keyboard answer.
 */

void kb_answervis_code( void )
{
  int i;

  if( kb_answer.stat == ACQDIS ) return;
  gotoxy( AnswerCodePosX, AnswerCodePosY );
  printf( "                " ); /* clear field for backspace operation */
  gotoxy( 0, AnswerCodePosY+1 );
  printf( "                " ); /* clear field for backspace operation */
  gotoxy( 0, AnswerCodePosY+2 );
  printf( "                " ); /* clear field for backspace operation */

  gotoxy( AnswerCodePosX, AnswerCodePosY );
  if( strlen( kb_answer.datab ) <= 16 )
    printf( "%s", kb_answer.datab );
  else
  {
    for( i = 0; i <= 15; i++ )
       putchar( kb_answer.datab[ i ] );
    gotoxy( 0, AnswerCodePosY+1 );
    if( strlen( kb_answer.datab ) <= 32 )
      for( i = 16; i < strlen( kb_answer.datab ); i++ )
        putchar( kb_answer.datab[ i ] );
    else
    {
      for( i = 16; i <= 31; i++)
        putchar( kb_answer.datab[ i ] );
      gotoxy( 0, AnswerCodePosY+2 );
      for( i = 32; i < strlen( kb_answer.datab ); i++)
        putchar( kb_answer.datab[ i ] );
    }
  }
}

/*
 * Display decoder quantity answer.
 */
void dec_answervis_qnty( void )
{
  if( dec_answer.stat == ACQDIS ) return;

  gotoxy( AnswerRsPosX, AnswerRsPosY );
  printf( "                " );           /* clear field for backspace operation */
  gotoxy( AnswerRsPosX, AnswerRsPosY );
  printf( "%s", dec_answer.datab );
}
/*
 * Display keyboard answer.
 */

void kb_answervis_qnty( void )
{
  if( kb_answer.stat == ACQDIS ) return;
  gotoxy( AnswerRsPosX, AnswerRsPosY );
  printf( "                " );           /* clear field for backspace operation */
  gotoxy( AnswerRsPosX, AnswerRsPosY );
  printf( "%s", kb_answer.datab );
}

/*
 * Display keyboard answer.
 */

void kb_answervis_meals( void )
{
  if( kb_answer.stat == ACQDIS ) return;
  gotoxy( AnswerMealsPosX, AnswerMealsPosY );
  printf( "                " );           /* clear field for backspace operation */
  gotoxy( AnswerMealsPosX, AnswerMealsPosY );
  printf( "%s", kb_answer.datab );
}

void kb_answervis_location(void)
{
  if(kb_answer.stat == ACQDIS)return;
  gotoxy(9, 1);
  printf( "                ");
  gotoxy(9, 1);
  printf("%s", kb_answer.datab);
}

void dec_answervis_meals( void )
{
  if( dec_answer.stat == ACQDIS ) return;

  gotoxy( AnswerMealsPosX, AnswerMealsPosY );
  printf( "                " );           /* clear field for backspace operation */
  gotoxy( AnswerMealsPosX, AnswerMealsPosY );
  printf( "%s", dec_answer.datab );
}

void kb_answervis_pass(void)
{
 if(kb_answer.stat == ACQDIS) return;
 gotoxy( AnswerPassPosX, AnswerPassPosY);
 printf("                 ");
 gotoxy(AnswerPassPosX, AnswerPassPosY);
 printf("%s", kb_answer.datab );
}

void kb_answervis_month(void)
{
 if(kb_answer.stat == ACQDIS) return;
 gotoxy( AnswerMonthPosX, AnswerMonthPosY);
 printf("                 ");
 gotoxy(AnswerMonthPosX, AnswerMonthPosY);
 printf("%s", kb_answer.datab );
}

void kb_answervis_date(void)
{
 if(kb_answer.stat == ACQDIS) return;
 gotoxy( AnswerDatePosX, AnswerDatePosY);
 printf("                 ");
 gotoxy(AnswerDatePosX, AnswerDatePosY);
 printf("%s", kb_answer.datab+2 );
}

void kb_answervis_year(void)
{
 if(kb_answer.stat == ACQDIS) return;
 gotoxy( AnswerYearPosX, AnswerYearPosY);
 printf("                 ");
 gotoxy(AnswerYearPosX, AnswerYearPosY);
 printf("%s", kb_answer.datab+4 );
}


/*
 * Display application title.
 */

void prt_title( void )
{
  gotoxy( 0, 1 );	
  printf( "\f Meals Support" );
  gotoxy( 0, 2 );
  printf( "  Application" );
}

/*
 * Display reception title.
 */

void prt_rx_title( void )
{
  printf( "\f Meal Support" );
  gotoxy( 0, 1 );
  printf( "  Application" );
}

/*
 * Clear the internal database.
 */

void db_init( void )
{
  dbase = 0x8000;  /* physical allocation of dbase pointer */
  irecx = 0;
}

/*
 * Procedure that compact the database.
 */

void del_record( void )
{
  int i;

  for( i = frecx+1; i < irecx; i++ )
  {
    read_record( i );
    rw_record = rd_record;
    write_record( i-1, &rw_record );
  }
  irecx--;
  frecx--;

  if (irecx != 0)
    read_record( frecx );
}

#pragma EJ
/****************************** PUBLIC PROCEDURES *****************************/

/**************************** APPLICATION STARTUP *****************************/

/*
* Procedure called only at the first power-up
* insert here all conditions or initializations that must be performed
* the first time the application program is run
* (initializations, allocations, etc)
*/

void apl_startup( void )
{
	symblg( SY_ENABLE, SY_MSI );
	symblg( SY_ENABLE, SY_INT25 );
	symblg( SY_ENABLE, SY_IND25 );
	symblg( SY_ENABLE, SY_MONARCH );
	symblg( SY_ENABLE, SY_CODE128 );
	symblg( SY_ENABLE, SY_UPC_EAN );

	set_events(USB_EVENT);

	set_psssd_time( 20 SECONDS );
	
	icon_battery( 0 );

//	dbase = 0x8000;                   /* phisical allocation of dbase's pointer */
//	db_init();

	nextstep = FIRST_START;
} /* end apl_startup() */

/**************************** APPLICATION RESTART *****************************/

/*
* Procedure called at every power-up, except the first
* insert here all conditions or initializations that must be performed
* any time the wand will be woken up, after startup
*/

void apl_restart( void )
{
 	cable_insert_check();  
     if(USB_cable_Insertion_State())  
	 {
	 	 icon_on(ICON_USB,ICON_SECOND);
		 nextstep = PREPARE_COMMUNICATION;
	 }                                 
  	 else
	 {
	 	 nextstep = laststep;
	 }
} /* end apl_restart() */

#pragma EJ
/***************************** APPLICATION START ******************************/

/*
* Procedure called at every power-up (both startup & restart)
* insert here all conditions or initializations that must be performed
* every time the application program is run
*/

void apl_start( void )
{
	dec_habort();
	kb_habort();

	rdytsk( PROC_TKAPL );
//Connection Monitor is not active
	slptsk( PROC_TKUSERAPL3 );	
} /* end apl_start() */		   

#pragma EJ
/*********************************** EVENTS ***********************************/

/*
* This session contains procedures called from external modules to notify
* events.
* They must be declared in this module, otherwise unresolved external will
* appear.
* They are used typically to wake-up and synchronize the application
* with low-level events controlled by handlers.
*/

void dec_event( void )
{
	rdytsk( PROC_TKAPL );
}

void kb_event( void )
{
	rdytsk( PROC_TKAPL );
}

void ir_event( void )	// used by: rf.lib, newrf.lib, rf1.lib
{
}

void rf_event( void )	// used by: hdlrf.lib
{
}

/* Procedure is called when USB cable is inserted to prepare 
   USB communication */
void prepare_usb_com(void)
{
  dec_habort();
  kb_habort();
  ring( G5_RN, MEDIUM_RD, 1 );
  led( OFFLEDS );
  
  nextstep = PREPARE_COMMUNICATION;
  rdytsk( PROC_TKAPL );

}

void insertion_event( void )
{

 	if(USB_cable_event())
	{
	    icon_on(ICON_USB,ICON_SECOND);
	 	prepare_usb_com();
		rdytsk( PROC_TKAPL );
	}

	ring( F5_RN, MEDIUM_RD, 1 );
}

void extraction_event( void )
{
	if(USB_cable_extracted())
	{
		icon_off(ICON_SECOND);
		Connection_abort();
 
		nextstep = CLEAR_START;
 		rdytsk( PROC_TKAPL );	
 		 
	}
	ring( F5_RN, MEDIUM_RD, 1 );
}

void second_event( void )
{
	  rdytsk( PROC_TKUSERAPL1 );

}

void batt_warning_event( unsigned char level )
{
	icon_battery( level );
	red_battery_level(level); 
}

void batt_warning_off_event( void )
{
	icon_battery( 0 );
}

/*
* during shut-down any tasks may be found in DLYTSK status;
* if this happens the operating system will re-execute the tasks after
* next start-up.
* If you don't want this to happen put these tasks in SLPTSK status.
*/

void shut_down_event( void )
{
	slptsk( PROC_TKRING );
}


/*
 * Functions called by keyboard handler to signal activities on keyboard
 * They must be declared in this module, otherwise unresolved external will
 * appear.
 */

void kb_hactiv_consol( unsigned char key_code )	// only ENTER is available for 630 
{
  switch( key_code )
  {
    case MULTIPLE0:

      break;

    case MULTIPLE1:

      break;

    case MULTIPLE2:

      break;

    case MULTIPLE3:

      break;

    case ENTER:
      break;

    case BACKSPACE:

      break;

    case SHIFT:

      break;

    case ENDSHIFTIMER:

      break;

    case SHIFTSTATUS:
      break;

    case ENDSHIFTSTATUS:
      break;

    case ERROR:
      break;

    default:
      break;
  } /* case */
}

void kb_hactiv_arrows( unsigned char key_code )
{
  switch( key_code )
  {
    case LFT:
      break;
    case RGT:
      break;
    case UP:
		if(ifReviewData == TRUE){
			get_up_record();
		}
      break;
    case DWN:
		if(ifReviewData == TRUE){
			get_dwn_record();
		}
      break;
    case LFTRGTARROWS:			// only for 630 
      break;
    case UPDWNARROWS:			// only for 630 
      break;
    default:
      break;
  } /* case */
}

void kb_hactiv_functn( unsigned char key_code ) // only ESC is available for 630
{
  switch( key_code )
  {
   case F1:
	if(ifFirstPage)
	   	nextstep = ASK_CODE;	
	if(ifReviewData){
		dec_habort();
		kb_habort();
		nextstep = ASK_CONFIRM_DEL;
	}
	if(ifSetup)
	{
		nextstep = SETDATE;
	}
	if(ifWaitSpecial){
			gotoxy(0,4);
			printf("Enter Count:");
			nextstep = SPECIAL_COUNT;
	  		kb_hreqst( KB_QUESTION[ 8 ] );
      		slptsk( PROC_TKAPL );
	}
	if(ifMeals){
			nextstep = GUEST_MEALS;
	}
	if(ifSpecialEnter){
			nextstep = SPECIAL_COUNT;
	}
	if(ifAskResId){
			nextstep = DUPLICATE_RESID;
	}

 /*    if( find_loop )
      {
		dec_habort();
		kb_habort();
		nextstep = ASK_CONFIRM_DEL;
      }
*/
    	break;
    case F2:
	  	if(ifFirstPage)
			nextstep = REVIEW_DATA;
	  	if(ifSetup)
	  		nextstep = SET_LOCATION;
	  	if(ifWaitSpecial){
	  		nextstep = SPECIAL_AMOUNT;
	  	}
	  	if(ifMeals){
	  		nextstep= SPECIAL_CODES;	
	  	}
		if(ifSpecialEnter){
			nextstep = SPECIAL_AMOUNT;
		}
      	break;
    case F3:
		if(ifMainFrame)	{
			nextstep = ASK_PASS;
		}
	    if(ifFirstPage){
			nextstep = TRANSFER_DATA_VERIFY;  	/* transfer data verify */
		}
		if(ifAskResId){
			nextstep = REVIEW_DATA;
		}
		if(ifMeals){
			nextstep = NEW_MEALCODES;
		}
		break; 
    case F4:
		if(ifFirstPage){
			nextstep = MAIN_FRAME;
		}else if(ifSetup){
			nextstep = MAIN_FRAME;
		}else if(ifReviewData){
		    find_loop = FALSE;
			nextstep = CLEAR_START;
		}else 
			nextstep = CLEAR_START;
		break;
    case ESC:	// (UPANDDWN for 630)
		if(ifReviewData){
			ring( G5_RN, MEDIUM_RD, 1 );
      		nextstep = ASK_CONFIRM_DEL;
      	}
		if(ifAskConfirmDel){
			ring( G5_RN, MEDIUM_RD, 1 );
			nextstep = REVIEW_DATA;
		}
		if(ifMainFrame){
		   	nextstep = RESET_DATA;
		}
      break;
    default:
      break;
  } /* case */
}

void kb_hactiv_sfnctn( unsigned char key_code ) // function never called for 630
{
  switch( key_code )
  {
    case F1:

      break;
    case F2:

      break;
    case F3:

      break;
    case F4:

      break;
    case ESC: // (SEND for 660). ESC or SEND to be enabled by SECTSENDIR section 
      break;
    default:
      break;
  } /* case */
}

void kb_hactiv_onkeys( void )
{
}


void process_frame( unsigned char chr )
{
	/* The parity is already controlled */

	switch( rx_status )
	{
	case START_OF_BLOCK :
		/* Wait to receive the start of block character or ack/nak character */
		if ( wait_ack == TRUE )
		{
			bIsConnectionActive=TRUE;			
			if ( chr == ACK_CHR )
			{
				nextstep = RX_ACK;
			}
			else
			{
				nextstep = RX_NAK;
			}
			rdytsk( PROC_TKAPL );
			wait_ack = FALSE;
		}
		else
		{
			if ( chr == start_of_block )
			{
				/* Received start of character, next character must be the station
				address. */

				checksum = chr;
				rx_status = STATION_ADDRESS;
			}
		}
		return;
	case STATION_ADDRESS :
		/* Wait to receive the station address character */
		if ( chr == station_address )
		{
			/* Received start of character,
			next characters must be the command
			data. */
			checksum += chr;
			inrx = 0;
			rx_status = COMMAND;
		}
		else
		{
			/* If the station address is not correct, the message is for
			another terminal. */
			rx_status = START_OF_BLOCK;
		}
		return;
	case COMMAND :
		/* Store the command characters until the end of text character or more than MAX_RX_BUFFER
		chracters are received.
		If more than MAX_RX_BUFFER characters received, the command is wrong and the terminal
		is still waiting the start of block character.
		If the end of text character is received the next two characters are the checksum of
		the frame.
		*/

		if ( chr != end_of_text )
		{
			if  ( inrx < MAX_RX_BUFFER )
			{
				rx_buffer[ inrx ] = chr;
				inrx++;
			}
			else
				rx_status = START_OF_BLOCK;
		}
		else
			rx_status = CHK_HIGH_DIGIT;
		checksum += chr;
		return;
	case CHK_HIGH_DIGIT :
		/* This is the msb of the checksum. It is in ASCII format.
		It must be converted in decimal format.
		*/
		if ( chr >= 'A' )
			chr -= 0x37;
		else
			chr -= 0x30;
		rx_checksum = chr << 4;
		rx_status = CHK_LOW_DIGIT;
		return;
	case CHK_LOW_DIGIT :
		/* This is the lsb of the checksum. It is in ASCII format.
		It must be converted in decimal format.
		*/

		if ( chr >= 'A' )
			chr -= 0x37;
		else
			chr -= 0x30;
		rx_checksum += chr;
		rx_status = END_OF_BLOCK;
		return;
	case END_OF_BLOCK :
			bIsConnectionActive=TRUE;		

		/* In this status it is verified that the checksum of the receive frame
		is equal to the checksum transmitted from host.
		*/

		if ( ( chr == end_of_block ) && ( rx_checksum == checksum ) )
			nextstep = TX_ACK;
		else
			nextstep = TX_NAK;
		rdytsk( PROC_TKAPL );
		rx_status = START_OF_BLOCK;
		return;
	}
}


void transmission_routine()
{
	usbser_tx_message(tx_buffer);
}



/*************** High level transmit routine ******************************/

void send_message( char *message )
{
	unsigned char chk;
	unsigned char chr;
	unsigned char digit;
	unsigned char ix;
	static unsigned int wait_command_counter;
	static unsigned char x;

	ix = 0;
	/* Put start of block character */

	chk =  tx_buffer[ intx++ ] = start_of_block;

	/* Put station address character */

	chk += tx_buffer[ intx++ ] = station_address;

	/* Put data characters */

	while( message[ ix ] != 0 )
		chk += tx_buffer[ intx++ ] = message[ ix++ ];
		
	/* Put end of text character */

	chk += tx_buffer[ intx++ ] = end_of_text;

	/* Calculate and insert the checksum */

	digit = chk >> 4 ;
	if ( digit > 9 )
		tx_buffer[ intx++ ] = digit + 0x37;
	else
		tx_buffer[ intx++ ] = digit + 0x30;
	digit = chk & 0x0f;
	if ( digit > 9 )
		tx_buffer[ intx++ ] = digit + 0x37;
	else
		tx_buffer[ intx++ ] = digit + 0x30;

	/* Put end of block character */

	tx_buffer[ intx++ ] = end_of_block;

	/* The next reception must be the acknowledge characters */

	tx_buffer[ intx] ='\0';
	transmission_routine();

	for(ix=0;ix<= intx;ix++)tx_buffer[ ix]=0;  
	
	wait_ack= TRUE; 
	
	nextstep = RECEIVE_PROCESS_FRAME;	
} 

/*
* Date/Time transmission command handling procedure.
*/


unsigned char tx_parm( void )
{
	unsigned int i = 0;

	switch( rx_buffer[ Cmd_Chr_Pos ] )
	{
	case 'Z':
		sscanf( main_date+6, "%2s", &communication_buffer[ i ] );
		i += 2;
	case 'Y':
		sscanf( main_date+3, "%2s", &communication_buffer[ i ] );
		i += 2;
	case 'X':
		sscanf( main_date, "%2s", &communication_buffer[ i ] );
		i += 2;
		tx_datab[ i ] = '\0';
		break;
	case 'W':
		sscanf( main_time, "%2s", &communication_buffer[ i ] );
		i += 2;
	case 'V':
		sscanf( main_time+3, "%2s", &communication_buffer[ i ] );
		i += 2;
	case '\\':
		sscanf( main_time+6, "%2s", &communication_buffer[ i ] );
		tx_datab[ i+2 ] = '\0';
		break;
	default :
		return( NOK );
	}

	return( OK );
}

/*
* Date/Time setting command handling procedure.
*/

unsigned char set_parm( char * str )
{
	struct time orologio;

	sscanf( main_date+6, "%2bu", &orologio.year );
	sscanf( main_date+3, "%2bu", &orologio.month );
	sscanf( main_date, "%2bu", &orologio.day );
	sscanf( main_time, "%2bu", &orologio.hour );
	sscanf( main_time+3, "%2bu", &orologio.min );
	sscanf( main_time+6, "%2bu", &orologio.sec );

	switch( rx_buffer[ Cmd_Chr_Pos ] )
	{
	case 'Z':
		if( ( sscanf( str, "%2bu", &orologio.year ) ) == 0 )
			return( NOK );
		if( strlen( str ) == 2 )
		{
			writeclock( orologio );
			break;
		}
		str = str+2;
	case 'Y':
		if( ( sscanf( str, "%2bu", &orologio.month ) ) == 0 )
			return( NOK );
		if( orologio.month > 12 )
			return( NOK );
		if( strlen( str ) == 2 )
		{
			writeclock( orologio );
			break;
		}
		str = str+2;
	case 'X':
		if( ( sscanf( str, "%2bu", &orologio.day ) ) == 0 )
			return( NOK );
		if( orologio.month > 31 )
			return( NOK );
		if( strlen( str ) == 2 )
		{
			writeclock( orologio );
			break;
		}
		str = str+2;
	case 'W':
		if( ( sscanf( str, "%2bu", &orologio.hour ) ) == 0 )
			return( NOK );
		if( orologio.hour > 23 )
			return( NOK );
		if( strlen( str ) == 2 )
		{
			writeclock( orologio );
			break;
		}
		str = str+2;
	case 'V':
		if( ( sscanf( str, "%2bu", &orologio.min ) ) == 0 )
			return( NOK );
		if( orologio.hour > 59 )
			return( NOK );
		if( strlen( str ) == 2 )
		{
			writeclock( orologio );
			break;
		}
		str = str+2;
	case '\\':
		if( ( sscanf( str, "%2bu", &orologio.sec ) ) == 0 )
			return( NOK );
		if( orologio.hour > 59 )
			return( NOK );
		writeclock( orologio );
		break;
	}

	command_type = SET_DATE_TIME;
	return( OK );
}

/*
* Serial command interpreter procedure.
*/

unsigned char cmdint( void )
{

	/* Control that the command data is an escape sequence */

	if (( rx_buffer[ Esc_Chr_Pos ] != ESC_CHR ) ||
		( rx_buffer[ inrx - 1 ] != ESC_CHR ))
	{
		strcpy( communication_buffer, "<NAK>" );
		return NOTHING;
	}
	else
	{

		/* Command interprete */

		switch( rx_buffer[ Cmd_Chr_Pos ] )
		{
			/* Read Write clock */
		case 'Z' :    /* yymmddhhmmss */
		case 'Y' :    /* mmddhhmmss   */
		case 'X' :    /* ddhhmmss     */
		case 'W' :    /* hhmmss       */
		case 'V' :    /* mmss         */
		case '\\':    /* ss           */
			if ( rx_buffer[  Cmd_Type_Chr_Pos ] != '?' )
			{   /* set clock */
				if ( set_parm( &rx_buffer[ Cmd_Type_Chr_Pos ] ) == OK )
					strcpy( communication_buffer, "<ACK>" );
				else
					strcpy( communication_buffer, "<NAK>" );
			}
			else /* Read clock */
				if ( tx_parm() == NOK )
					strcpy( communication_buffer, "<NAK>" );
			return NOTHING;

		case DEL_CMD :    /* Delete command */
			trecx = -1;
			switch( rx_buffer[ Cmd_Type_Chr_Pos ] )
			{
			case '*' :
				command_type = DEL_ALL_RECORDS;
				return DEL_ALL_RECORDS;
			default :
				strcpy( communication_buffer, "<NAK>" );
			}
			return NOTHING;

		case DMP_CMD :	/* Command for Dump all the data */
			trecx = -1;
			switch( rx_buffer[ Cmd_Type_Chr_Pos ] )
			{
			case '*' :
				command_type = DMP_ALL_RECORDS;
				return DMP_ALL_RECORDS;
			case '$' :
				command_type = DMP_DIRECTORY;
				return DMP_DIRECTORY;
			default :
				strcpy( communication_buffer, "<NAK>" );
			}
			return NOTHING;

		case ENQ_CMD : /* Enquiry */
			strcpy( communication_buffer, "<RUN>" );
			return NOTHING;

		case LBL_CMD : /* Display terminal informations */
			if ( (unsigned char)inrx > 3 )
			{
				switch ( rx_buffer[ Cmd_Type_Chr_Pos ] )
				{
				case '*' : /* Ram size */
					sprintf( communication_buffer, "%04dKbytes",
						(unsigned int )( ram_config() * 32 ) );
					break;
				case '$' : /* Program version */
					strcpy( communication_buffer, "Demo 3 " );
					break;
				case '!' : /* Developer name */
					strcpy( communication_buffer,"Written by Datalogic Mobile Srl" );
					break;
				default :
					strcpy( communication_buffer, "<NAK>" );
				}
			}
			else
				sprintf( communication_buffer, "%s",terminal_name() );
			return NOTHING;
		}
	}
}


/****************************** APLICATION TASKS ******************************/

void tkapl( void )
{
  unsigned int i;

  switch( nextstep )
  {
    STEP FIRST_START:                   /* initialization at first activation */
      find_loop = FALSE;  				/* Inspection mode disable */
      prt_title(); 
      dlytsk( PROC_TKAPL, T1SEC );
	  nextstep = MAIN_FRAME;
    ENDOFSTEP;

	STEP MAIN_FRAME:
	  turnOffOptions();
	  ifMainFrame = TRUE;
	  laststep = nextstep;
	  ifVerifyTransferData = FALSE;
	  ifReviewData = FALSE;
	  ifFirstPage = FALSE;
	  ifAskCode = FALSE; 
	  ifMainFrame = TRUE;
	  ifSetYear = FALSE;
	  printf("\f");
	  gotoxy(0, 1);
	  printf("BCMeals-");
	  gotoxy(9 , 1);
	  printf("%s", defaultLocation);
	  gotoxy(0, 4);
	  printf("%c%c/%c%c/%c%c", main_date[3], main_date[4], main_date[0], main_date[1], main_date[6], main_date[7]);
	  gotoxy(0, 7);
	  printf("F3=Setup F4=Cont");
	  kb_hreqst(KB_QUESTION[ 3 ]);
	  slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP ASK_PASS:
	  laststep = nextstep;
	  ifMainFrame = FALSE;
	  ifSetup = FALSE;
	  printf("\f");
	  kb_hreqst( KB_QUESTION[ 5 ] );
	  nextstep = WAIT_PASS;
	  slptsk( PROC_TKAPL );
	ENDOFSTEP;
  
	STEP WAIT_PASS:
	  kb_answervis_pass();
      if( kb_answer.stat == ACQEND ){					  
			if(!strcmp(kb_answer.datab, "911")){
				kb_habort();
        		dlytsk( PROC_TKAPL, T500MS );
				nextstep = SETUP;
			}else{
				nextstep = MAIN_FRAME;
			}
      	}else slptsk( PROC_TKAPL );
	ENDOFSTEP;


	STEP SETUP:
	  kb_habort();
	  ifSetup = TRUE;
	  printf("\f");
	  gotoxy(0,1);
	  printf("F1=Set Date/Time");
	  gotoxy(0,2);
	  printf("F2=Set Location");
	  gotoxy(0,3);
	  printf("F4=Exit");
	  kb_hreqst(KB_QUESTION[3]);
	  slptsk(PROC_TKAPL);
	ENDOFSTEP;

	STEP SET_LOCATION:
	   printf("\f");
	   kb_hreqst(KB_QUESTION[7]);
	   nextstep = WAIT_SETLOCATION;
	   slptsk( PROC_TKAPL);
	ENDOFSTEP;

	STEP WAIT_SETLOCATION:
	  kb_answervis_location();
	  if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      	{					  // In 630 it is suggested to keep for portability.
			strcpy(defaultLocation, kb_answer.datab);    
			kb_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = MAIN_FRAME;
      	}else slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP SETDATE:		  /*check validation*/
	  printf("\f");
	  gotoxy(0,1);
	  printf("Current Date:");
	  gotoxy(0, 2);
	  printf("%c%c/%c%c/%c%c", main_date[3], main_date[4], main_date[0], main_date[1], main_date[6], main_date[7]);
	  gotoxy(0, 4);
	  printf("Enter New Date:");
	  kb_hreqst( KB_QUESTION[ 6 ] );
	  nextstep = WAIT_SETMONTH;
	  slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_SETMONTH:				  /*check validation*/
	  kb_answervis_month();
      if( kb_answer.len == 2 ){	
	       	sscanf(kb_answer.datab,"%2bu",&changedTime.month);
			gotoxy(2,5);
			printf("/");
	  		nextstep = WAIT_SETDATE;
	  		slptsk( PROC_TKAPL );
      	}else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = SETTIME;
		}else {
			slptsk(PROC_TKAPL);
		}
	ENDOFSTEP;

	STEP WAIT_SETDATE:				 /*check validation */
	  kb_answervis_date();
	  if(kb_answer.len == 4){
			sscanf(kb_answer.datab+2,"%2bu",&changedTime.day);
	  		gotoxy(5,5);
			printf("/");
			nextstep = WAIT_SETYEAR;
	  		slptsk( PROC_TKAPL );	
	  }else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = SETTIME;
		}else {
			slptsk(PROC_TKAPL);
		}
	ENDOFSTEP;

	STEP WAIT_SETYEAR:
	  kb_answervis_year();
	  ifSetYear = TRUE;
	  if(kb_answer.len == 6){
			sscanf(kb_answer.datab+4,"%2bu",&changedTime.year);
			kb_habort();
			kb_hreqst( KB_QUESTION[ 3 ]);
			nextstep = WAIT_DATEENTER;	
			slptsk( PROC_TKAPL );
	  }else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = SETTIME;
		}else {
			slptsk(PROC_TKAPL);
		}
	ENDOFSTEP;

	STEP WAIT_DATEENTER:
		 sscanf( main_time, "%2bu", &changedTime.hour );
		 sscanf( main_time+3, "%2bu", &changedTime.min );
		 sscanf( main_time+6, "%2bu", &changedTime.sec );
		 changedTime.dayofw = 0;
		 writeclock(changedTime); 
		 kb_habort();
		 dlytsk(PROC_TKAPL, T500MS);
		 nextstep = SETTIME;
	ENDOFSTEP;

	STEP SETTIME:		  /*check validation*/
	  printf("\f");
	  gotoxy(0,1);
	  printf("Current Time:");
	  gotoxy(0, 2);
	  printf("%c%c:%c%c:%c%c", main_time[0], main_time[1], main_time[3], main_time[4], main_time[6], main_time[7]);
	  gotoxy(0, 4);
	  printf("Enter New Time:");
	  kb_hreqst( KB_QUESTION[ 6 ] );
	  nextstep = WAIT_SETHOUR;
	  slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_SETHOUR:				  /*check validation*/
	  kb_answervis_month();
      if( kb_answer.len == 2 ){	
	        sscanf(kb_answer.datab,"%2bu",&changedTime.hour);
			gotoxy(2,5);
			printf(":");
	  		nextstep = WAIT_SETMIN;
	  		slptsk( PROC_TKAPL );
      	}else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = MAIN_FRAME;
		}else {
			slptsk(PROC_TKAPL);
		}
	ENDOFSTEP;

	STEP WAIT_SETMIN:				 /*check validation */
	  kb_answervis_date();
	  if(kb_answer.len == 4){
			sscanf(kb_answer.datab+2,"%2bu",&changedTime.min);
	  		gotoxy(5,5);
			printf(":");
			nextstep = WAIT_SETSEC;
	  		slptsk( PROC_TKAPL );	
	  }else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = MAIN_FRAME;
	  }else {
			slptsk(PROC_TKAPL);
	}
	ENDOFSTEP;

	STEP WAIT_SETSEC:
	  kb_answervis_year();
	  ifSetYear = TRUE;
	  if(kb_answer.len == 6){
			sscanf(kb_answer.datab+4,"%2bu",&changedTime.sec);
			kb_habort();
			kb_hreqst( KB_QUESTION[ 3 ] );
			nextstep = WAIT_TIMEENTER;	
			slptsk( PROC_TKAPL );
	  }else if(kb_answer.stat == ACQEND){
			kb_habort();
			nextstep = MAIN_FRAME;
		}else {
			slptsk(PROC_TKAPL);
	  }
	ENDOFSTEP;

	STEP WAIT_TIMEENTER:
	  sscanf( main_date +3, "%2bu", &changedTime.month );
	  sscanf( main_date, "%2bu", &changedTime.day );
	  sscanf( main_date+6, "%2bu", &changedTime.year );
	  changedTime.dayofw = 0;
	  kb_habort();
	  writeclock(changedTime);  
	  dlytsk(PROC_TKAPL, T500MS);
	  nextstep = MAIN_FRAME;
	ENDOFSTEP;
	   
    STEP CLEAR_START:
	  laststep = nextstep;
	  slptsk( PROC_TKUSERAPL2 );
	  turnOffOptions();
	  ifFirstPage = TRUE;
	  kb_habort();                          						/* clear display entry point */
      printf( "\f" );
	  gotoxy(0,0);
	  printf("F1=Collect Data");
	  gotoxy(0,1);
	  printf("F2=Review Data");
	  gotoxy(0,2);
	  printf("F3=Transfer File");
	  gotoxy(0,3);
	  printf("F4=Exit");
	  kb_hreqst(KB_QUESTION[ 3 ]);
      slptsk( PROC_TKAPL );
    ENDOFSTEP;
	  
    STEP ASK_CODE:
	  turnOffOptions(); 
	  ifAskCode = TRUE;
	  kb_habort();
	  dlytsk( PROC_TKAPL, T500MS ); 
	  if( irecx < DBASE_ITEMS )                      				/* dbase full condition */
      {
	    laststep = nextstep;
	  	printf("\f");              					               /* decoder activation & buffer full check */
      	gotoxy(0,0);
	  	printf("This Meal is...");
	  	gotoxy(0,4);
	  	printf("Val=00-99");
		gotoxy(0,6);
	  	printf("F4=Exit");
        dec_hreqst( DEC_QUESTION[ 0 ] );
		kb_hreqst( KB_QUESTION[ 0 ] );
        nextstep = WAIT_CODE;
        slptsk( PROC_TKAPL );
      }
      else
      {
        nextstep = DBASE_FULL;
      }
    ENDOFSTEP;

    STEP WAIT_CODE:
      kb_answervis_code();
	  ring( G5_RN, MEDIUM_RD, 1 );
      	if( dec_answer.stat == ACQEND )
      	{
		    stringToInteger = atoi(dec_answer.datab);	
			if(!(dec_answer.len < 2 || dec_answer.len > 2))
			{
	  				dec_answervis_code();
					ring( G5_RN, MEDIUM_RD, 1 );
	  				strcpy( wr_record.barcode, dec_answer.datab );
					strcpy(defaultBarcode, dec_answer.datab);
					dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
					nextstep = ASK_RESID;
			}else{
				printf( "\nInvalid Code" );
	  			dec_habort();
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
	  			nextstep = ASK_CODE;
			}
      	}else if( dec_answer.stat == ACQNOV ) 
      		{
				printf( "\nInvalid Code" );
				dec_habort();
     			kb_habort();
				dlytsk( PROC_TKAPL, T500MS );
	  			nextstep = ASK_CODE;
      		}else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      		{
			    ring( G5_RN, MEDIUM_RD, 1 );
				if(!( kb_answer.len < 2 || kb_answer.len > 2))
				{
				    strcpy( wr_record.barcode, kb_answer.datab );
					strcpy(defaultBarcode, kb_answer.datab);

					dec_habort();
					kb_habort();
        			dlytsk( PROC_TKAPL, T500MS );
					nextstep = ASK_RESID;
	  				
				}else{;
  					printf( "\nInvalid Code" );
	  				dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = ASK_CODE;
			}
								  // In 630 it is suggested to keep for portability.
      		}else slptsk( PROC_TKAPL );
    ENDOFSTEP;

	STEP ASK_RESID:
	turnOffOptions();
	ifAskResId = TRUE;
	gotoxy( 0, 0 );
    printf( "                " );           /* clear field for backspace operation */
	gotoxy( AnswerRsPosX, AnswerRsPosY );
    printf( "                " );           /* clear field for backspace operation */
	gotoxy( AnswerMealsPosX, AnswerMealsPosY );
    printf( "                " );           /* clear field for backspace operation */
	gotoxy( 0, 3 );
	printf( "                ");
	gotoxy( 0, 5 );
    printf( "                " );           /* clear field for backspace operation */
	gotoxy( 0, 6 );			 
    printf( "                " );           /* clear field for backspace operation */
	if( irecx < DBASE_ITEMS )                      	/* dbase full*/
     {
	 	ifResId = TRUE;	 
	 	laststep = nextstep;
		gotoxy(0,7);
		
		if(ifAcceptMealCode){							
	  		strcpy( wr_record.barcode, defaultBarcode);		/* 	saves the default barcode to the list.*/
	    }
	  	dec_hreqst( DEC_QUESTION[ 1 ] );
      	kb_hreqst( KB_QUESTION[ 1 ] );             	/* decoder activation & buffer full check */
		gotoxy(0,3);
		printf("                     ");
      	gotoxy(0,2);
	  	printf("#Meals:");
	  	gotoxy(0,4);
	  	printf("F1=Duplicate     ");
		gotoxy(0,5);
		printf("F3=Review Data   ");
		gotoxy(0,6);
		printf("F4=Exit");
      	nextstep = WAIT_RESID;
		ifAcceptMealCode = FALSE;
      	slptsk( PROC_TKAPL );
	 }else{
        nextstep = DBASE_FULL;
	 }
    ENDOFSTEP;

	STEP DUPLICATE_RESID:
	  ring( G5_RN, MEDIUM_RD, 1 );
	  if(strcmp(duplicateResidentId,"")==1){
	    gotoxy(AnswerRsPosX,AnswerRsPosY);
		printf( "                " );
		gotoxy( AnswerRsPosX, AnswerRsPosY );
		printf("%s", duplicateResidentId);
		strcpy( wr_record.res, duplicateResidentId );
		nextstep = ASK_MEALS;
	  }else{
	  	gotoxy(0,3);
		printf("No Dup ResId");
	    nextstep = ASK_RESID;
	  }
	ENDOFSTEP;

	STEP WAIT_RESID:
	  kb_answervis_qnty();
	  ring( G5_RN, MEDIUM_RD, 1 );
	  if( dec_answer.stat == ACQEND )
      {
	  	if(dec_answer.len > 6 ){
		    ring( G5_RN, MEDIUM_RD, 1 );
			gotoxy(0,3);
	  		printf( "Invalid Res Id" );
	  		kb_habort();
			dec_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_RESID;
		}else{
	  		dec_answervis_qnty();
			ring( G5_RN, MEDIUM_RD, 1 );
	  		strcpy( wr_record.res, dec_answer.datab );
	  		dec_habort();
	  		kb_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_MEALS;
		}
      }else if( dec_answer.stat == ACQNOV ){
	    ring( G5_RN, MEDIUM_RD, 1 );
        gotoxy( 0, 3 );
		printf( "Invalid Res Id" );
		kb_habort();
		dlytsk( PROC_TKAPL, T500MS );
		nextstep = ASK_RESID;
      }else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      {					  // In 630 it is suggested to keep for portability.
	    if(kb_answer.len > 6 ){
		    ring( G5_RN, MEDIUM_RD, 1 );
			gotoxy(0, 3);
	  		printf( "Invalid Res Id" );
	  		kb_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_RESID;
		}else{
			strcpy( wr_record.res, kb_answer.datab );
			ring( G5_RN, MEDIUM_RD, 1 );
			kb_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = ASK_MEALS;
		}
      }
      else slptsk( PROC_TKAPL );
    ENDOFSTEP;  
	
    STEP ASK_MEALS:
	  	turnOffOptions();
	  	ifMeals = TRUE;
	  	gotoxy(0,7);
	  	printf("                    ");
	  	gotoxy(0,3);
	  	printf("F1=Guest Meals");
	  	gotoxy(0,4);
	  	printf("F2=Special Codes");						  
	  	gotoxy(0,5);
		printf("F3=New MealCode");
		gotoxy(0,6);
		printf("F4=Clear/Exit");											  
	    kb_hreqst( KB_QUESTION[ 2 ] );
		dec_hreqst( DEC_QUESTION[ 2 ] );
	    nextstep = WAIT_MEALS;
	    slptsk( PROC_TKAPL );
    ENDOFSTEP;

    STEP WAIT_MEALS:
      kb_answervis_meals();
	  ring( G5_RN, MEDIUM_RD, 1 );
	if( dec_answer.stat == ACQEND ){
	  	if( (strcmp(dec_answer.datab, "1")==0) || (strcmp(dec_answer.datab, "2") == 0)){
		    strcpy( wr_record.meals, dec_answer.datab );
			dec_answervis_meals();
			dec_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = WRITE_RECORD;
		}else{
	  		gotoxy(0,7);
	  		printf( "Invalid Meals" );
	  		dec_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_MEALS;
		}
      }else if( dec_answer.stat == ACQNOV ){
	    ring( G5_RN, MEDIUM_RD, 1 );
        gotoxy( 0, 7 );
		printf( "Invalid Meals" );
		dec_habort();
		dlytsk( PROC_TKAPL, T500MS );
		nextstep = ASK_MEALS;
      }else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      {					  // In 630 it is suggested to keep for portability.
	    if( (strcmp(kb_answer.datab, "1")==0) || (strcmp(kb_answer.datab, "2") == 0)){
	  		strcpy( wr_record.meals, kb_answer.datab );
			kb_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = WRITE_RECORD;
		}else{
			gotoxy(0,7);
	  		printf( "Invalid Meals" );
	  		kb_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_MEALS;
		}
      }else slptsk( PROC_TKAPL );

    ENDOFSTEP;

	STEP RESET_DATA:
		laststep = MAIN_FRAME;
		turnOffOptions();
		ifResetData = TRUE;
		printf("\f");
		gotoxy(0,4);
		printf("Erase All Data?");
		gotoxy(0,5);
		printf("Enter / Esc");
		nextstep = WAIT_RESET;
		kb_hreqst(KB_QUESTION[3]);
		slptsk(PROC_TKAPL);	
	ENDOFSTEP;

	STEP WAIT_RESET:
		kb_habort();
		turnOffOptions();
		ifMainFrame = TRUE;
		dbase = 0x8000;                   /* physical allocation of dbase's pointer */
  		db_init();
		irecx = 0;
		frecx = 0;
		nextstep = MAIN_FRAME;
	ENDOFSTEP;

	STEP NEW_MEALCODES:
	  	turnOffOptions();
		ifNotMealCode = TRUE;
	  	printf("\f");
	  	gotoxy(0,0);
	  	printf("**New Mealcode**");
	  	gotoxy(0,6);
	  	printf("F4=Clear/Exit");
	  	kb_hreqst( KB_QUESTION[ 0 ] );
      	nextstep = WAIT_NEWMEALCODE;
      	slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_NEWMEALCODE:
	   kb_answervis_code();
	   ring( G5_RN, MEDIUM_RD, 1 );
      	if( dec_answer.stat == ACQEND )
      	{
			stringToInteger = atoi(dec_answer.datab);
			if((stringToInteger >= 50) || (stringToInteger < 20))
			{
	  			printf( "\nNot val Code" );
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
	  			nextstep = NEW_MEALCODES;
			}
        	else
			{
	  			dec_answervis_code();
				ring( G5_RN, MEDIUM_RD, 1 );
	  			strcpy( wr_record.barcode, dec_answer.datab );
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
				nextstep = ASK_NEWMEALCODE_MEALS;
			}
      	}else if( dec_answer.stat == ACQNOV ){
				gotoxy(0, 7);
	  			printf( "\nNot val Code" );
				dec_habort();
     			kb_habort();
				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = NEW_MEALCODES;
      	}else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      	{					  // In 630 it is suggested to keep for portability.
				stringToInteger = atoi(kb_answer.datab);
		        if((stringToInteger >= 50) || (stringToInteger < 20))
				{
	  				gotoxy(0, 7);
	  				printf( "\nNot val Code" );
	  				dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = NEW_MEALCODES;
				}
        		else
				{
					ring( G5_RN, MEDIUM_RD, 1 );
	  				strcpy( wr_record.barcode, kb_answer.datab );
	  				dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
					nextstep = ASK_NEWMEALCODE_MEALS;
				}
      	}else slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP ASK_NEWMEALCODE_MEALS:	
	    gotoxy(0,2);
	    printf("#Meals=");								  
      	dec_hreqst( DEC_QUESTION[ 2 ] );
      	kb_hreqst( KB_QUESTION[ 2 ] );
      	nextstep = WAIT_MEALS;
      	slptsk( PROC_TKAPL );		
	ENDOFSTEP;

	STEP SPECIAL_CODES:
	  	turnOffOptions();
	  	ifMeals = TRUE;
		ifNotMealCode = TRUE;
	  	printf("\f");
	  	gotoxy(0,0);
	  	printf("**Special Code**");
		gotoxy(0,5);
		printf("Val=50-99");
	  	gotoxy(0,6);
	  	printf("F4=Clear/Exit");
	  	kb_hreqst( KB_QUESTION[ 0 ] );
		dec_hreqst( DEC_QUESTION[ 0 ] );
      	nextstep = WAIT_SPECIAL;
      	slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_SPECIAL:
	  kb_answervis_code();
	  ring( G5_RN, MEDIUM_RD, 1 );
      	if( dec_answer.stat == ACQEND )
      	{
		  stringToInteger = atoi(dec_answer.datab);
			if((stringToInteger >= 50) && (stringToInteger < 100))
			{
				dec_answervis_code();
				ring( G5_RN, MEDIUM_RD, 1 );
	  			strcpy( wr_record.barcode, dec_answer.datab );
	  			dec_habort();
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
				nextstep = ASK_SPECIALENTER;

			}else{
	  			gotoxy(0, 7);
	  			printf( "\nInvalid Code" );
	  			dec_habort();
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
	  			nextstep = SPECIAL_CODES;
			}
      	}else if( dec_answer.stat == ACQNOV ) 
      		{
				gotoxy(0, 7);
	  			printf( "\nInvalid Code" );
				dec_habort();
     			kb_habort();
				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = SPECIAL_CODES;
      		}
      		else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      		{					  // In 630 it is suggested to keep for portability.
				stringToInteger = atoi(kb_answer.datab);
				if((stringToInteger >= 50) && (stringToInteger < 100))
				{
					strcpy( wr_record.barcode, kb_answer.datab );
					dec_habort();
					kb_habort();
        			dlytsk( PROC_TKAPL, T500MS );
					nextstep = ASK_SPECIALENTER;
				}else{
	  				gotoxy(0, 7);
	  				printf( "\nNot val Code" );
	  				dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = SPECIAL_CODES;
				}
      		}else slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP ASK_SPECIALENTER:
	  turnOffOptions();
	  ifSpecialEnter = TRUE;
	  printf("\f");
	  gotoxy(0,0);
	  printf("F1=Enter Count");
	  gotoxy(0,2);
	  printf("F2=Enter Amount");
	  gotoxy(0,6);
	  printf("F4=Exit");
	  kb_hreqst(KB_QUESTION[ 3 ]);
      slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP SPECIAL_COUNT:
	  kb_habort();
	  printf("\f");
	  gotoxy(0,0);
	  printf("**Special Code**");
	  gotoxy(0,1);
	  printf("Meal Code=");
	  gotoxy(10,1);
	  printf("%s", wr_record.barcode);
	  gotoxy(0,2);
	  printf("Count=");
	  gotoxy(0,6);
	  printf("F4=Exit");
	  kb_hreqst( KB_QUESTION[ 2 ] );
      nextstep = WAIT_SPECIALCOUNT;
      slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_SPECIALCOUNT:
	  kb_answervis_meals();
	  ring( G5_RN, MEDIUM_RD, 1 );
	  if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      {					  // In 630 it is suggested to keep for portability.
		strcpy( wr_record.meals, kb_answer.datab );	 //save data on the correct entry
		kb_habort();
        dlytsk( PROC_TKAPL, T500MS );
		nextstep = WRITE_RECORD;
      }else
	  	slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP SPECIAL_AMOUNT:
	  printf("\f");
	  gotoxy(0,0);
	  printf("**Special Code**");
	  gotoxy(0,1);
	  printf("Meal Code=");
	  gotoxy(10,1);
	  printf("%s", wr_record.barcode);
	  gotoxy(0,2);
	  printf("Amount=");
	  gotoxy(0,6);
	  printf("F4=Clear/Exit");
	  kb_hreqst(KB_QUESTION[8]);
	  nextstep = WAIT_SPECIALAMOUNT;
	  slptsk(PROC_TKAPL);
	ENDOFSTEP;

	STEP WAIT_SPECIALAMOUNT:
	  kb_answervis_meals();
	  ring( G5_RN, MEDIUM_RD, 1 );
	  if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      {					  // In 630 it is suggested to keep for portability.
		strcpy( wr_record.amt, kb_answer.datab );	   //save data on the correct entry
		strcpy( wr_record.meals, "1");
		kb_habort();
        dlytsk( PROC_TKAPL, T500MS );		 
		nextstep = WRITE_RECORD;
      }else
	   	slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP GUEST_MEALS:
	  ifGuestMeals = TRUE;
	  printf("\f");
	  gotoxy(0,0);
	  printf("**Guest Meals**");
	  gotoxy(0,1);
	  printf("Meal Code=");
	  //gotoxy(0,2);
	  //printf("#Meals=");
	  gotoxy(0,5);
	  printf("Val=20-49");
	  gotoxy(0,6);
	  printf("F4=Clear/Exit");
	  dec_hreqst( DEC_QUESTION[ 0 ] );
	  kb_hreqst( KB_QUESTION[ 0 ] );
      nextstep = WAIT_GUESTMEALCODE;
      slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_GUESTMEALCODE:
	    kb_answervis_code();
		ring( G5_RN, MEDIUM_RD, 1 );
      	if( dec_answer.stat == ACQEND )
      	{
		    stringToInteger = atoi(dec_answer.datab);
			if((stringToInteger < 20) || (stringToInteger > 49))
			{
	  			gotoxy(0, 7);
	  			printf( "\nNot val Code" );
	  			dec_habort();
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
	  			nextstep = GUEST_MEALS;
			}
        	else
			{
	  			dec_answervis_code();
				ring( G5_RN, MEDIUM_RD, 1 );
	  			strcpy( wr_record.barcode, dec_answer.datab );
	  			dec_habort();
	  			kb_habort();
	  			dlytsk( PROC_TKAPL, T500MS );
				nextstep = ASK_GUESTMEALS;	  
			}
      	}else if( dec_answer.stat == ACQNOV )
      		{
				gotoxy(0, 7);
	  			printf( "\nNot val Code" );
				dec_habort();
     			kb_habort();
				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = GUEST_MEALS;
      		}
      		else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      		{					  // In 630 it is suggested to keep for portability.
			   stringToInteger = atoi(kb_answer.datab);
			   if( stringToInteger < 20 || stringToInteger > 49)
				{
	  				gotoxy(0, 7);
	  				printf( "\nNot val Code" );
	  				dec_habort();
	  				kb_habort();
	  				dlytsk( PROC_TKAPL, T500MS );
	  				nextstep = GUEST_MEALS;
				}else
				{
					strcpy( wr_record.barcode, kb_answer.datab );
					dec_habort();
					kb_habort();
        			dlytsk( PROC_TKAPL, T500MS );
					nextstep = ASK_GUESTMEALS;
				}
      		}else slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP ASK_GUESTMEALS:
	  gotoxy(0,5);
	  printf("             ");
	  gotoxy(0,2);
	  printf("#Meals=");
      kb_hreqst( KB_QUESTION[ 2 ] );
      nextstep = WAIT_GUESTMEALS;																  
      slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_GUESTMEALS:
	  kb_answervis_meals();
	  ring( G5_RN, MEDIUM_RD, 1 );
	  if( dec_answer.stat == ACQEND ){
	  	if( (dec_answer.len > 0) && (dec_answer.len < 3)&&(strcmp(dec_answer.datab,"0")==1)&&(strcmp(dec_answer.datab,"00")==1)){
		    strcpy( wr_record.meals, dec_answer.datab );
			dec_answervis_meals();
			dec_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = WRITE_RECORD;
		}else{
			gotoxy(0,7);
	  		printf( "Val=1,2" );
	  		dec_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_MEALS;
		}
      }else if( dec_answer.stat == ACQNOV ){
	    ring( G5_RN, MEDIUM_RD, 1 );
        gotoxy( 0, 7 );
		printf( "Invalid Meals" );
		dec_habort();
		dlytsk( PROC_TKAPL, T500MS );
		nextstep = ASK_MEALS;
      }else if( kb_answer.stat == ACQEND ) // In 630 is useful for default string acquisition.
      {					  // In 630 it is suggested to keep for portability.
	   if( (kb_answer.len > 0) && (kb_answer.len < 3)&&(strcmp(kb_answer.datab,"0")==1)&&(strcmp(kb_answer.datab,"00")==1)){
		    strcpy( wr_record.meals, kb_answer.datab );
			kb_habort();
        	dlytsk( PROC_TKAPL, T500MS );
			nextstep = WRITE_RECORD;
		}else{
			gotoxy(0, 7);
	  			printf( "Val=1,2" );
	  		kb_habort();
	  		dlytsk( PROC_TKAPL, T500MS );
	  		nextstep = ASK_GUESTMEALS;
		}
      }else slptsk( PROC_TKAPL );  
	ENDOFSTEP;

	STEP REVIEW_DATA:
	  laststep = nextstep;
	  turnOffOptions();
	  ifReviewData = TRUE;
	  if(get_dwn_record() == NOK){
	  	printf("\f");
	  	gotoxy(0,1);
	  	printf("No Data To Show");
		gotoxy(0,6);
	  	printf("F4=Clear/Exit");
		kb_habort();
		kb_hreqst( KB_QUESTION[ 3 ] );
		slptsk( PROC_TKAPL );
	  }else{
	  	kb_hreqst( KB_QUESTION[ 3 ] );
		slptsk( PROC_TKAPL );
	  }
	ENDOFSTEP;

    STEP WRITE_RECORD:
	  ifAcceptMealCode = TRUE;
      strcpy(duplicateResidentId,wr_record.res );
	  strcpy( wr_record.location, defaultLocation);
      wr_record.time_info = main_clock;
      write_record( irecx, &wr_record );
	  strcpy(wr_record.amt, "");
      irecx++;
      nextstep = ASK_RESID;
    ENDOFSTEP;

    STEP DBASE_FULL:           /* database full handling */
      kb_hreqst( KB_QUESTION[ 4 ] );
      slptsk( PROC_TKAPL );
    ENDOFSTEP;

	STEP TRANSFER_DATA_VERIFY:
		ifVerifyTransferData = TRUE;
		laststep = nextstep;
	   	printf("\f");
	   	gotoxy(0,1);
	   	printf("Connect cable");
		gotoxy(0,2);
		printf("and open");
		gotoxy(0,3);
		printf("C:/meals");
		gotoxy(0,4);
		printf("Click on");
		gotoxy(0,5);
		printf("makeFile. Wait");
		gotoxy(0,6);
		printf("for a beep.");
		gotoxy(0,7);
		printf("Now click on");
		gotoxy(0,8);
		printf("uploadFile.");
		gotoxy(0,9);
		printf("Wait until");
		gotoxy(0,10);
		printf("the program is");
		gotoxy(0,11);
		printf("back up.Done");															  
		gotoxy(0,13);
	  	printf("F4=Clear/Exit");
		kb_hreqst(KB_QUESTION[ 3 ]);
		slptsk(PROC_TKAPL);
	ENDOFSTEP;

	STEP PREPARE_COMMUNICATION:  /* prepare communication */
	stop_psssd();
	if(usb_open(USBserial)== TRUE)	   /* Check for USB enumeration success */
	{
		gotoxy(0,0);
		printf( "\fConnected" );
		//Connection_Monitor_start();

		/* communication buffer initializzation */

		inrx  = 0;           /* pointer to the input receive character */
		intx  = 0;           /* pointer to the input transmission character */
		outtx = 0;           /* pointer to the output transmission character */

		/* Status of receive interrupt routine */

		rx_status = START_OF_BLOCK;

		/* Control frame characters */

		start_of_block  = STX_CHR;    /* STX character */
		station_address = SOH_CHR;     /* SOH character */
		end_of_text     = ETX_CHR;    /* ETX character */
		end_of_block    = EOB_CHR;    /* CR  character */

		wait_ack        = FALSE;   /* Wait command */


		nextstep = RECEIVE_PROCESS_FRAME;

	}

	else
		{
		    gotoxy(0,4);
		    printf("USB Enumeration");
			gotoxy(0,5);
		    printf("Fail");
		    delay_ms(200);
		    delay_ms(200);
		    delay_ms(200);
		    delay_ms(200);
			usb_close();					/* Close USB communication */
			icon_off(ICON_SECOND);
			icon_mail(OFF);

		}

	ENDOFSTEP;


	STEP RECEIVE_PROCESS_FRAME:						/* first frame handling */
		while(usbser_rx_ready())
		{
			process_frame(usbser_rx_char());		
		}		   
		retrig_psssd(); //prevent to suspend during connection
	
	ENDOFSTEP;							   

	STEP TX_ACK:
	tx_buffer[ 0 ] = ACK_CHR; 		/* ack character */
	intx  = 0;              			/* Transmit only one character */
	outtx = 0;
	usbser_tx_char(tx_buffer[0]);
	switch ( cmdint() )
	{
	case DMP_DIRECTORY :    /* Header */
	case DMP_ALL_RECORDS :
		if( irecx >= 999 )
			sprintf( communication_buffer, "FORMULA%s 0-999",terminal_name() );
		else
			sprintf( communication_buffer, "FORMULA%s 0-%03d",terminal_name(), irecx );
		break;
	case DEL_ALL_RECORDS:
	  db_init();
	  ring( D6_RN, MAX_RD, 1 );
	  ifDataPresent = TRUE;
	  printf("\f");
	  gotoxy(0,5);
	  printf("Data Transfer");
	  gotoxy(0,6);
	  printf("Complete");
	  gotoxy(0,7);
	  printf("Disconnect");
	  gotoxy(0,8);
	  printf("cable and");
	  gotoxy(0,9);
	  printf("click on");
	  gotoxy(0,10);	   
	  printf("uploadFile to");
	  gotoxy(0,11);
	  printf("upload data to");
	  gotoxy(0,12);
	  printf("ATCare");
	  strcpy( communication_buffer, "<DEL>" );
	  break;
	}
	send_message( communication_buffer );
	trecx++;	
	rdytsk( PROC_TKAPL );
	ENDOFSTEP;	
	
	STEP TX_NAK :
	tx_buffer[ 0 ] = NAK_CHR; /* nak character */
	intx  = 0;              /* Transmit only one character */
	outtx = 0;
	usbser_tx_char(tx_buffer[0]);
	rdytsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP RX_ACK :
	switch ( command_type )
	{
	case DMP_DIRECTORY :
		if( trecx == 0 )
		{
			strcpy( communication_buffer, "01  entries (45)" );
			send_message( communication_buffer );
			trecx++;
		}
		else if( trecx == 1 )
		{
			sprintf( communication_buffer, "%06ld bytes free", (unsigned int)( (DBASE_ITEMS-irecx)*sizeof( wr_record ) ) );
			send_message( communication_buffer );
			trecx++;
		}
		else if( trecx == 2 )
		{
			strcpy( communication_buffer, "<EOT>" );
			send_message( communication_buffer );
			trecx++;
		}
		break;
	case DMP_ALL_RECORDS :
		if( trecx < irecx )
		{
			icon_mail(ON);
			
			read_record( trecx );
			read_record( trecx );
	    sprintf( communication_buffer, "%s|%s|%s|%s|%02bu/%02bu/%02bu|%02bu:%02bu:%02bu|",
		rd_record.res,
		rd_record.barcode,
		rd_record.meals,
		rd_record.amt,
		rd_record.time_info.month,
  	    rd_record.time_info.day,
	    rd_record.time_info.year,
	    rd_record.time_info.hour,
	    rd_record.time_info.min,
		rd_record.time_info.sec);
			intx  = 0;
			outtx = 0;
			send_message( communication_buffer );
			trecx++;
		}
		else if( trecx == irecx )
		{
			if(!(ifDataPresent)){
				printf("\f");
	  			gotoxy(0,5);
	  			printf("No Data");
	  			gotoxy(0,6);
	  			printf("to Transfer");
	  			gotoxy(0,7);
	  			printf("Disconnect");
			}
				strcpy( communication_buffer, "<EOF>" );
				intx  = 0;
				outtx = 0;
				send_message( communication_buffer );
				trecx++;
			
		}
		else if( trecx == irecx + 1 )
		{
			strcpy( communication_buffer, "<EOT>" );
			intx  = 0;
			outtx = 0;
			icon_mail(OFF);
			send_message( communication_buffer );
			trecx++;
		}
		else
		{	
			icon_mail(OFF);
			nextstep = RECEIVE_PROCESS_FRAME;
		}
		break;
	case SET_DATE_TIME:
		prev_min = main_time[ 4 ];
		icon_time( main_time );
		nextstep = RECEIVE_PROCESS_FRAME;
	}
	inrx  = 0;          
	ENDOFSTEP;

	STEP RX_NAK :
	send_message( communication_buffer );
	inrx  = 0;         
	ENDOFSTEP;

	STEP ASK_CONFIRM_DEL:
	laststep = REVIEW_DATA;
	  turnOffOptions();
	  ifAskConfirmDel = TRUE;
	printf( "\f" );
	gotoxy( 0, 1 );
	printf( "Delete Cur.Rec?" );
	gotoxy( 0, 2 );
	printf( " (ENTER / ESC) " );

	kb_hreqst( KB_QUESTION[ 3 ] );
	nextstep = WAIT_CONFIRM_DEL;
	slptsk( PROC_TKAPL );
	ENDOFSTEP;

	STEP WAIT_CONFIRM_DEL:
	  kb_habort();
	  turnOffOptions();
	  ifReviewData = TRUE;
	  del_record();
	  printf("\f");
	  nextstep = REVIEW_DATA;
    ENDOFSTEP;

	STEP REMOVE_USB_CABLE:
		gotoxy(0,1);
		printf("Remove USB cable");
 		slptsk( PROC_TKAPL );  
	ENDOFSTEP;

default:                                                /* wrong selector */
	fault( PROC_TKAPL, 1, nextstep );
	nextstep = FIRST_START;
	} /* case */
}

/*
* User available task;
* used for time display; woken up by second_event() each second
*/

void tkuserapl1( void )
{
	if( prev_min != main_time[ 4 ] )      /* main_time updated every minute */
	{
		prev_min = main_time[ 4 ];
		icon_time( main_time );
	}
	slptsk( PROC_TKUSERAPL1 );
}

/*
* Not used tasks
*/


void tkuserapl2( void )
{
}

void Connection_abort()
{
	usb_close();
	//Stop the Connection Monitor
	slptsk( PROC_TKUSERAPL3 );
}

void  Connection_Monitor_start()
{
	bIsConnectionActive=TRUE;
	rdytsk( PROC_TKUSERAPL3 );
}


//The Connection Monitor  checks the connection is still active
void tkuserapl3( void )
{
	if(bIsConnectionActive)
	{
		bIsConnectionActive=FALSE;
		dlytsk( PROC_TKUSERAPL3, T2SEC );	
	}	
	else
	{
		gotoxy(0,0);
		printf("Not connected   ");
		Connection_abort();	
		nextstep = REMOVE_USB_CABLE;				 
	}
}

void rxchcom( unsigned char chr )
{

}

